using MicroMsg.Common.Utils;
using MicroMsg.Protocol;
using Microsoft.Phone.Data.Linq;
using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Linq;
using System.Reflection;
namespace MicroMsg.Storage
{
	public class StorageUpdater
	{
		private const string TAG = "StorageUpdater";
		private static bool isTable(FieldInfo info)
		{
			return info.get_FieldType().get_IsGenericType() && info.get_FieldType().GetGenericTypeDefinition() == typeof(Table);
		}
		public static Dictionary<string, Type> getTable(Type type_0)
		{
			if (type_0 == null)
			{
				return null;
			}
			Dictionary<string, Type> dictionary = new Dictionary<string, Type>();
			FieldInfo[] fields = type_0.GetFields(20);
			for (int i = 0; i < fields.Length; i++)
			{
				FieldInfo fieldInfo = fields[i];
				if (StorageUpdater.isTable(fieldInfo))
				{
					Type type = fieldInfo.get_FieldType().GetGenericArguments()[0];
					dictionary.Add(type.get_Name(), type);
				}
			}
			return dictionary;
		}
		private static bool isColumn(MemberInfo memberInfo_0)
		{
			object[] customAttributes = memberInfo_0.GetCustomAttributes(true);
			for (int i = 0; i < customAttributes.Length; i++)
			{
				object obj = customAttributes[i];
				if (obj is ColumnAttribute)
				{
					return true;
				}
			}
			return false;
		}
		public static List<string> getColumn(Type type_0)
		{
			if (type_0 == null)
			{
				return null;
			}
			List<string> list = new List<string>();
			MemberInfo[] members = type_0.GetMembers(52);
			MemberInfo[] array = members;
			for (int i = 0; i < array.Length; i++)
			{
				MemberInfo memberInfo = array[i];
				if ((memberInfo.get_MemberType() == 4 || memberInfo.get_MemberType() == 16) && StorageUpdater.isColumn(memberInfo))
				{
					list.Add(memberInfo.get_Name());
				}
			}
			return list;
		}
		public static bool needUpdateSchema(Type dbType, StorageDBSchema dbSchema)
		{
			if (dbType == null || dbSchema == null)
			{
				return false;
			}
			if (dbSchema.version == ConstantsProtocol.CLIENT_VERSION)
			{
				return false;
			}
			DebugEx.getTimeSpan();
			StorageUpdater.schema_patch_1_2(dbSchema);
			Dictionary<string, Type> table = StorageUpdater.getTable(dbType);
			List<string> list = Enumerable.ToList<string>(Enumerable.Select<KeyValuePair<string, List<string>>, string>(dbSchema.tables, (KeyValuePair<string, List<string>> keyValuePair_0) => keyValuePair_0.get_Key()));
			using (Dictionary<string, Type>.Enumerator enumerator = table.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					KeyValuePair<string, Type> current = enumerator.get_Current();
					if (!list.Contains(current.get_Key()))
					{
						bool result = true;
						return result;
					}
					List<string> column = StorageUpdater.getColumn(current.get_Value());
					List<string> list2 = dbSchema.tables.get_Item(current.get_Key());
					List<string> list3 = Enumerable.ToList<string>(Enumerable.Except<string>(column, list2));
					if (Enumerable.Count<string>(list3) > 0)
					{
						bool result = true;
						return result;
					}
				}
			}
			Log.smethod_4("StorageUpdater", "check needUpdateSchema time=" + DebugEx.getTimeSpan());
			return false;
		}
		public static bool updateSchema(Type dbType, StorageDBSchema dbSchema, DataContext dataContext_0)
		{
			if (dbType != null && dbSchema != null && dataContext_0 != null)
			{
				DatabaseSchemaUpdater databaseSchemaUpdater = Extensions.CreateDatabaseSchemaUpdater(dataContext_0);
				DebugEx.getTimeSpan();
				bool result;
				try
				{
					string text = "";
					int num = 0;
					Dictionary<string, Type> table = StorageUpdater.getTable(dbType);
					List<string> list = Enumerable.ToList<string>(Enumerable.Select<KeyValuePair<string, List<string>>, string>(dbSchema.tables, (KeyValuePair<string, List<string>> keyValuePair_0) => keyValuePair_0.get_Key()));
					using (Dictionary<string, Type>.Enumerator enumerator = table.GetEnumerator())
					{
						while (enumerator.MoveNext())
						{
							KeyValuePair<string, Type> current = enumerator.get_Current();
							if (!list.Contains(current.get_Key()))
							{
								MethodInfo method = databaseSchemaUpdater.GetType().GetMethod("AddTable");
								MethodInfo methodInfo = method.MakeGenericMethod(new Type[]
								{
									current.get_Value()
								});
								methodInfo.Invoke(databaseSchemaUpdater, null);
								dbSchema.tables.set_Item(current.get_Key(), StorageUpdater.getColumn(current.get_Value()));
								num++;
								text += string.Format(",addTable={0}", current.get_Key());
							}
							else
							{
								List<string> addColumnList = StorageUpdater.getAddColumnList(current.get_Value(), dbSchema);
								if (addColumnList != null)
								{
									using (List<string>.Enumerator enumerator2 = addColumnList.GetEnumerator())
									{
										while (enumerator2.MoveNext())
										{
											string current2 = enumerator2.get_Current();
											MethodInfo method2 = databaseSchemaUpdater.GetType().GetMethod("AddColumn");
											MethodInfo methodInfo2 = method2.MakeGenericMethod(new Type[]
											{
												current.get_Value()
											});
											methodInfo2.Invoke(databaseSchemaUpdater, new object[]
											{
												current2
											});
											text += string.Format(",addColumn={0} ", current.get_Key() + "." + current2);
											num++;
											dbSchema.tables.get_Item(current.get_Key()).Add(current2);
										}
									}
								}
							}
						}
					}
					Log.smethod_4("StorageUpdater", string.Concat(new object[]
					{
						"update proc num=",
						num,
						",proc=",
						text
					}));
					DatabaseSchemaUpdater expr_22C = databaseSchemaUpdater;
					expr_22C.set_DatabaseSchemaVersion(expr_22C.get_DatabaseSchemaVersion() + 1);
					databaseSchemaUpdater.Execute();
					dataContext_0.SubmitChanges();
					Log.smethod_4("StorageUpdater", "update time=" + DebugEx.getTimeSpan());
					result = true;
				}
				catch (Exception ex)
				{
					Log.smethod_1("storage", " updateDataBase exception " + ex);
					result = false;
				}
				return result;
			}
			return false;
		}
		public static bool addTable(DataContext dataContext_0, Type tabType, StorageDBSchema dbSchema)
		{
			if (dataContext_0 != null && tabType != null && dbSchema != null)
			{
				bool result;
				try
				{
					Log.smethod_5("StorageUpdater", "addTable  name=" + tabType.get_Name());
					DatabaseSchemaUpdater databaseSchemaUpdater = Extensions.CreateDatabaseSchemaUpdater(dataContext_0);
					DebugEx.getTimeSpan();
					MethodInfo method = databaseSchemaUpdater.GetType().GetMethod("AddTable");
					MethodInfo methodInfo = method.MakeGenericMethod(new Type[]
					{
						tabType
					});
					methodInfo.Invoke(databaseSchemaUpdater, null);
					DatabaseSchemaUpdater expr_67 = databaseSchemaUpdater;
					expr_67.set_DatabaseSchemaVersion(expr_67.get_DatabaseSchemaVersion() + 1);
					databaseSchemaUpdater.Execute();
					dataContext_0.SubmitChanges();
					dbSchema.tables.set_Item(tabType.get_Name(), StorageUpdater.getColumn(tabType));
					result = true;
				}
				catch (Exception ex)
				{
					Log.smethod_1("storage", " addTable exception " + ex);
					throw;
				}
				return result;
			}
			return false;
		}
		public static List<string> getAddColumnList(Type tabType, StorageDBSchema dbSchema)
		{
			List<string> column = StorageUpdater.getColumn(tabType);
			List<string> list = dbSchema.tables.get_Item(tabType.get_Name());
			List<string> list2 = Enumerable.ToList<string>(Enumerable.Except<string>(column, list));
			if (Enumerable.Count<string>(list2) <= 0)
			{
				return null;
			}
			return list2;
		}
		public static bool syncColumn(DataContext dataContext_0, Type tabType, StorageDBSchema dbSchema)
		{
			if (dataContext_0 == null || tabType == null || dbSchema == null)
			{
				return false;
			}
			if (!dbSchema.tables.ContainsKey(tabType.get_Name()))
			{
				return false;
			}
			bool result;
			try
			{
				Log.smethod_5("StorageUpdater", "add column name=" + tabType.get_Name());
				DatabaseSchemaUpdater databaseSchemaUpdater = Extensions.CreateDatabaseSchemaUpdater(dataContext_0);
				DebugEx.getTimeSpan();
				List<string> addColumnList = StorageUpdater.getAddColumnList(tabType, dbSchema);
				if (addColumnList == null)
				{
					result = false;
				}
				else
				{
					using (List<string>.Enumerator enumerator = addColumnList.GetEnumerator())
					{
						while (enumerator.MoveNext())
						{
							string current = enumerator.get_Current();
							MethodInfo method = databaseSchemaUpdater.GetType().GetMethod("AddColumn");
							MethodInfo methodInfo = method.MakeGenericMethod(new Type[]
							{
								tabType
							});
							methodInfo.Invoke(databaseSchemaUpdater, new object[]
							{
								current
							});
							dbSchema.tables.get_Item(tabType.get_Name()).Add(current);
						}
					}
					databaseSchemaUpdater.Execute();
					result = true;
				}
			}
			catch (Exception ex)
			{
				Log.smethod_1("storage", " add column exception " + ex);
				throw;
			}
			return result;
		}
		public static StorageDBSchema schema_patch_getSchema10001()
		{
			return StorageXml.loadResObject<StorageDBSchema>(new Uri("Resource/Xml/db_schema10001.xml", 2));
		}
		public static StorageDBSchema getSchemaFromType(Type dbType)
		{
			StorageDBSchema storageDBSchema = new StorageDBSchema();
			storageDBSchema.version = ConstantsProtocol.CLIENT_VERSION;
			Dictionary<string, Type> table = StorageUpdater.getTable(dbType);
			using (Dictionary<string, Type>.Enumerator enumerator = table.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					KeyValuePair<string, Type> current = enumerator.get_Current();
					List<string> column = StorageUpdater.getColumn(current.get_Value());
					storageDBSchema.tables.set_Item(current.get_Key(), column);
				}
			}
			return storageDBSchema;
		}
		private static void schema_patch_1_2(StorageDBSchema dbSchema)
		{
			if (dbSchema != null && dbSchema.tables.ContainsKey("EmojiArt"))
			{
				if (!dbSchema.tables.get_Item("EmojiArt").Contains("_version"))
				{
					dbSchema.tables.get_Item("EmojiArt").Add("_version");
					dbSchema.tables.get_Item("EmojiArtGroup").Add("_version");
				}
				return;
			}
		}
		public static void test()
		{
			StorageBasic.onLogin("test");
			Log.smethod_5("StorageUpdater", "table list = " + StorageUpdater.getTable(typeof(StorageDB)).debugString());
			Log.smethod_5("StorageUpdater", "contact column = " + StorageUpdater.getColumn(typeof(Contact)).debugString());
			Log.smethod_5("StorageUpdater", "contact column = " + StorageUpdater.getColumn(typeof(Contact)).debugString());
			Log.smethod_5("StorageUpdater", "chatmsg column = " + StorageUpdater.getColumn(typeof(ChatMsg)).debugString());
			Log.smethod_5("StorageUpdater", "Qfriend = " + StorageUpdater.getColumn(typeof(QFriend)).debugString());
		}
	}
}
